package com.easy.tool.utils.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.easy.tool.anno.BeanDes;
import com.easy.tool.anno.MethodDes;
import com.easy.tool.entity.JwtEntity;
import org.apache.log4j.Logger;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 高俊
 * @create 2022-04-2022/4/17-13:31
 */
@BeanDes(name = "JWT工具类",des = "使用JWT生产token保存登入信息")
public class JwtUtils {

    private static Logger logger = Logger.getLogger(JwtUtils.class);


    /**
     * 生成jwt令牌
     * @param entity
     * @return
     */
    @MethodDes(des = "生成jwt令牌",explain = "使用密钥和关键数据生成jwt令牌",param = {"arg0-> entity：jwt使用的对象，用于存放header，payload，expire等"})
    public static String generJwt(JwtEntity entity){
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,entity.getExpire());

        String token = JWT.create()
                .withHeader(entity.getHeader())
                .withClaim("payload", entity.getPayload())
                .withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(entity.getSecret()));

        return token;
    }

    /**
     * 生成jwt令牌
     * @param secret
     * @param token
     * @return
     */
    @MethodDes(des = "解析jwt令牌",explain = "对jwt令牌进行解析获得payload数据",param = {"arg0-> entity：密钥","arg1-> token：jwt令牌"})
    public static Map<String, Object>  verifyJwt(String secret,String token){
        Map<String, Object> error = new HashMap<>();
        JWTVerifier build = JWT.require(Algorithm.HMAC256(secret)).build();
        try {
            DecodedJWT verify = build.verify(token);
            Map<String, Object> map = verify.getClaim("payload").asMap();
            return map;
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            logger.error("出现异常-> 无效签名");
            error.put("error","出现异常-> 无效签名");
        }catch (TokenExpiredException e){
            e.printStackTrace();
            logger.error("出现异常-> token过期");
            error.put("error","出现异常-> token过期");
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();
            logger.error("出现异常-> token无效");
            error.put("error","出现异常-> token无效");
        }catch (Exception e){
            e.printStackTrace();
            logger.error("出现异常-> token无效");
            error.put("error","出现异常-> token无效");
        }
        return error;

    }
}
